Completed
Push — master ( fcbd47...a4251b )
by Ruben de
01:00
created

m transaction #1ꞌ)   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
nc 1
dl 0
loc 11
rs 9.4285
nop 1
1
/* jshint -W101, -W098 */
2
var blocktrail = require('../');
3
var assert = require('assert');
4
var crypto = require('crypto');
5
6
/**
7
 * @type APIClient
8
 */
9
var client = blocktrail.BlocktrailSDK({
10
    apiKey : process.env.BLOCKTRAIL_SDK_APIKEY || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APIKEY",
11
    apiSecret : process.env.BLOCKTRAIL_SDK_APISECRET || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APISECRET"
12
});
13
14
describe('SDK general', function() {
15
    it('test Coin Value', function(cb) {
16
        assert.equal(blocktrail.toSatoshi(0.00000001), 1);
17
        assert.equal(blocktrail.toBTC(100000000), 1.0);
18
19
        assert.equal(blocktrail.toSatoshi(1.23456789), 123456789);
20
        assert.equal(blocktrail.toBTC(123456789), 1.23456789);
21
22
        cb();
23
    });
24
    it('test auth failure', function(cb) {
25
        var client = blocktrail.BlocktrailSDK({
26
            apiKey: "TESTKEY-FAIL",
27
            apiSecret: "TESTSECRET-FAIL"
28
        });
29
30
        client.address("1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp", function(err, address) {
0 ignored issues
show
Unused Code introduced by
The parameter address is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
31
            assert.ok(err);
32
33
            cb();
34
        });
35
    });
36
});
37
38
describe('data api', function() {
39
    it('test address', function(cb) {
40
        client.address("1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp", function(err, address) {
41
            assert.ifError(err);
42
            assert.ok(address['address']);
43
            assert.equal(address['address'], '1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp');
44
45
            cb();
46
        });
47
    });
48
    it('test addressTransactions', function(cb) {
49
        client.addressTransactions("1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp", {limit: 23}, function(err, address_txs) {
50
            assert.ifError(err);
51
            assert.ok(address_txs['data']);
52
            assert.ok(address_txs['total']);
53
            assert.ok(address_txs['data'].length === 23);
54
55
            cb();
56
        });
57
    });
58
    it('test addressUnconfirmedTransactions', function(cb) {
59
        client.addressUnconfirmedTransactions("1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp", {limit: 23}, function(err, address_txs) {
60
            assert.ifError(err);
61
            assert.ok('data' in address_txs);
62
            assert.ok('total' in address_txs);
63
            // assert.ok(address_txs['total'] >= address_txs['data'].length);
64
65
            cb();
66
        });
67
    });
68
    it('test addressUnspentOutputs', function(cb) {
69
        client.addressUnspentOutputs("16dwJmR4mX5RguGrocMfN9Q9FR2kZcLw2z", {limit: 23}, function(err, address_utxo) {
70
            assert.ifError(err);
71
            assert.ok('data' in address_utxo);
72
            assert.ok('total' in address_utxo);
73
            assert.ok(address_utxo['total'] >= address_utxo['data'].length);
74
75
            cb();
76
        });
77
    });
78
    it('test batchAddressUnspentOutputs', function(cb) {
79
        client.batchAddressUnspentOutputs(["16dwJmR4mX5RguGrocMfN9Q9FR2kZcLw2z", "16fVUD4yCuabS153FJGtmLL8tgydsrf6vu"], {limit: 23}, function(err, address_utxo) {
80
            assert.ifError(err);
81
            assert.ok('data' in address_utxo);
82
            assert.ok('total' in address_utxo);
83
            assert.ok(address_utxo['total'] >= address_utxo['data'].length);
84
            cb();
85
        });
86
    });
87
    it('test verifyAddress', function(cb) {
88
        client.verifyAddress("16dwJmR4mX5RguGrocMfN9Q9FR2kZcLw2z", "HPMOHRgPSMKdXrU6AqQs/i9S7alOakkHsJiqLGmInt05Cxj6b/WhS7kJxbIQxKmDW08YKzoFnbVZIoTI2qofEzk=", function(err, result) {
89
            assert.ifError(err);
90
            assert.ok(result);
91
92
            cb();
93
        });
94
    });
95
    it('test block by hash', function(cb) {
96
        client.block("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf", function(err, block) {
97
            assert.ifError(err);
98
            assert.ok(block['hash']);
99
            assert.equal(block['hash'], '000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf');
100
101
            cb();
102
        });
103
    });
104
    it('test block by height', function(cb) {
105
        client.block(200000, function(err, block) {
106
            assert.ifError(err);
107
            assert.ok(block['hash']);
108
            assert.equal(block['hash'], '000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf');
109
110
            cb();
111
        });
112
    });
113
    it('test blockTransactions', function(cb) {
114
        client.blockTransactions("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf", {limit: 23}, function(err, block_txs) {
115
            assert.ifError(err);
116
            assert.ok(block_txs['data']);
117
            assert.ok(block_txs['total']);
118
            assert.ok(block_txs['data'].length === 23);
119
120
            cb();
121
        });
122
    });
123
    it('test allBlocks', function(cb) {
124
        client.allBlocks({page:2, limit: 23, sort_dir: 'asc'}, function(err, blocks) {
125
            assert.ifError(err);
126
            assert.ok(blocks['data']);
127
            assert.ok(blocks['total']);
128
            assert.ok(blocks['data'].length === 23);
129
            assert.equal(blocks['data'][0]['hash'], '000000000cd339982e556dfffa9de94744a4135c53eeef15b7bcc9bdeb9c2182');
130
            assert.equal(blocks['data'][1]['hash'], '00000000fc051fbbce89a487e811a5d4319d209785ea4f4b27fc83770d1e415f');
131
132
            cb();
133
        });
134
    });
135
    it('test blockLatest', function(cb) {
136
        client.blockLatest(function(err, block) {
137
            assert.ifError(err);
138
            assert.ok(block['hash']);
139
140
            cb();
141
        });
142
    });
143
    it('test coinbase transaction', function(cb) {
144
        client.transaction("0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098", function(err, tx) {
145
            assert.ifError(err);
146
            assert.equal(tx['hash'], "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098");
147
            assert.equal(tx['enough_fee'], null);
148
149
            cb();
150
        });
151
    });
152
    it('test random transaction #1', function(cb) {
153
        client.transaction("c791b82ed9af681b73eadb7a05b67294c1c3003e52d01e03775bfb79d4ac58d1", function(err, tx) {
154
            assert.ifError(err);
155
            assert.equal(tx['hash'], "c791b82ed9af681b73eadb7a05b67294c1c3003e52d01e03775bfb79d4ac58d1");
156
            assert.ok(tx['confirmations']);
157
            assert.equal(tx['enough_fee'], true);
158
            assert.equal(tx['high_priority'], false);
159
160
            cb();
161
        });
162
    });
163
    it('test batch transactions', function(cb) {
164
        client.transactions([
165
            "c791b82ed9af681b73eadb7a05b67294c1c3003e52d01e03775bfb79d4ac58d1",
166
            "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",
167
            "4bbe6feeb50e47e2de5ef6a9d7378363823611dd07d4a5ea1799da9ae6a21665",
168
            "6c0d3156621051a86b8af3f23dfe211e8a17a01bffe3c2b24cbee65139873c6a",
169
            "356210d6b8143e23d0cf4d0dae0ac686015a13fe3b2b46b1cc43a71a36c73355",
170
            "a40d1eee0cec3d963d8df2870bd642bd3fd07163e864aeb90fa5efe9ea91c998",
171
            "1c7e3c9823baa9bb70b09ed666e8a6b3120b07f84429ed41f05d5504bd58f188",
172
            "1f0a168f0fceb6e48208b23ffb1ad528acfc11c30ab302d447743f2a0fc5fe80",
173
            "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" // not found
174
        ], function(err, txs) {
175
            assert.ifError(err);
176
177
            assert.equal(Object.keys(txs['data']).length, 8);
178
179
            var tx1 = txs['data']["c791b82ed9af681b73eadb7a05b67294c1c3003e52d01e03775bfb79d4ac58d1"];
180
            assert.equal(tx1['hash'], "c791b82ed9af681b73eadb7a05b67294c1c3003e52d01e03775bfb79d4ac58d1");
181
            assert.ok(tx1['confirmations']);
182
            assert.equal(tx1['enough_fee'], true);
183
            assert.equal(tx1['high_priority'], false);
184
185
            var tx2 = txs['data']["0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"];
186
            assert.equal(tx2['hash'], "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098");
187
            assert.equal(tx2['enough_fee'], null);
188
189
            var tx8 = txs['data']["1f0a168f0fceb6e48208b23ffb1ad528acfc11c30ab302d447743f2a0fc5fe80"];
190
            assert.equal(tx8['hash'], "1f0a168f0fceb6e48208b23ffb1ad528acfc11c30ab302d447743f2a0fc5fe80");
191
192
            assert.ok(!txs['data']['ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff']);
193
194
            cb();
195
        });
196
    });
197
});
198
199
describe('webhooks api', function() {
200
    var createdWebhooks = [];
201
    var cleanup = function(done) {
202
        client.allWebhooks({page:1, limit:500}, function(err, response) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
203
            //delete each webhook
204
            //var allWebhooks = response.data;
205
            if (!createdWebhooks.length) {
206
                done();
207
            }
208
            createdWebhooks.forEach(function(identifier) {
209
                client.deleteWebhook(identifier, function(err, response) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
210
                    createdWebhooks.splice(identifier, 1);
211
                    if (createdWebhooks.length === 0) {
212
                        done();
213
                    }
214
                });
215
            });
216
        });
217
    };
218
    before(function(done) {
219
        // runs before all tests in this block..cleanup any existing data that could conflict with the tests
220
        cleanup(done);
221
    });
222
    after(function(done) {
223
        //cleanup after all tests
224
        cleanup(done);
225
    });
226
227
    //create a custom (yet "random") identifier such to avoid conflicts when running multiple tests simultaneously
228
    var myIdentifier = crypto.randomBytes(24).toString('hex');
229
230
    // test cases
231
    it('create new webhook with custom identifier', function(done) {
232
        client.setupWebhook("https://www.blocktrail.com/webhook-test", myIdentifier, function(err, webhook) {
233
            assert.ifError(err);
234
            assert.equal(webhook.url, "https://www.blocktrail.com/webhook-test");
235
            assert.equal(webhook.identifier, myIdentifier);
236
            createdWebhooks.push(webhook.identifier);
237
            done();
238
        });
239
    });
240
241
    it('create new webhook with random identifier', function(done) {
242
        client.setupWebhook("https://www.blocktrail.com/webhook-test", function(err, webhook) {
243
            assert.ifError(err);
244
            assert.equal(webhook.url, "https://www.blocktrail.com/webhook-test");
245
            assert.ok(webhook.identifier);
246
            createdWebhooks.push(webhook.identifier);
247
            done();
248
        });
249
    });
250
251
    it('get all user webhooks', function(done) {
252
        client.allWebhooks(null, function(err, response) {
253
            assert.ifError(err);
254
            assert.ok('data' in response, "'data' key not in response");
255
            assert.ok('total' in response, "'total' key not in response");
256
            assert.ok(parseInt(response['total']) >= 2, "'total' does not match expected value");
257
            assert.ok(response['data'].length >= 2, "Count of webhooks returned is not equal to 2");
258
259
            assert.ok('url' in response['data'][0], "'url' key not in first webhook of response");
260
            assert.ok('url' in response['data'][1], "'url' key not in second webhook of response");
261
            done();
262
        });
263
    });
264
265
    it('get a single webhook', function(done) {
266
        client.getWebhook(createdWebhooks[0], function(err, response) {
267
            assert.ifError(err);
268
            assert.ok('url' in response, "'url' key not in response");
269
            assert.ok('identifier' in response, "'identifier' key not in response");
270
            assert.equal(response['url'], "https://www.blocktrail.com/webhook-test", "'url' does not match expected value");
271
            assert.equal(response['identifier'], myIdentifier, "'identifier' does not match expected value");
272
            done();
273
        });
274
    });
275
276
    it('delete a webhook', function(done) {
277
        client.deleteWebhook(createdWebhooks[0], function(err, response) {
278
            assert.ifError(err);
279
            assert.ok(response);
280
            done();
281
        });
282
    });
283
284
    it('update a webhook', function(done) {
285
        var newIdentifier = crypto.randomBytes(24).toString('hex');
286
        var newUrl = "https://www.blocktrail.com/new-webhook-url";
287
        client.updateWebhook(createdWebhooks[1], {identifier: newIdentifier, url: newUrl}, function(err, response) {
288
            assert.ifError(err);
289
            assert.ok('url' in response, "'url' key not in response");
290
            assert.ok('identifier' in response, "'identifier' key not in response");
291
            assert.equal(response['url'], newUrl, "'url' does not match expected value");
292
            assert.equal(response['identifier'], newIdentifier, "'identifier' does not match expected value");
293
294
            createdWebhooks[1] = newIdentifier;
295
            done();
296
        });
297
    });
298
299
    it('subscribe to address-transaction events', function(done) {
300
        var address = "1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp";
301
        client.subscribeAddressTransactions(createdWebhooks[1], address, 2, function(err, response) {
302
            assert.ifError(err);
303
            assert.ok('event_type' in response, "'event_type' key not in response");
304
            assert.ok('address' in response, "'address' key not in response");
305
            assert.ok('confirmations' in response, "'confirmations' key not in response");
306
            assert.equal(response['event_type'], "address-transactions", "'event_type' does not match expected value");
307
            assert.equal(response['address'], address, "'address' does not match expected value");
308
            assert.equal(response['confirmations'], 2, "'confirmations' does not match expected value");
309
            done();
310
        });
311
    });
312
313
    it('subscribe to transaction event', function(done) {
314
        var transaction = "a0a87b1577d606b349cfded85c842bdc53b99bcd49614229a71804b46b1c27cc";
315
        client.subscribeTransaction(createdWebhooks[1], transaction, 2, function(err, response) {
316
            assert.ifError(err);
317
            assert.ok('event_type' in response, "'event_type' key not in response");
318
            assert.ok('address' in response, "'address' key not in response");
319
            assert.ok('confirmations' in response, "'confirmations' key not in response");
320
            assert.equal(response['event_type'], "transaction", "'event_type' does not match expected value");
321
            assert.equal(response['transaction'], transaction, "'transaction' does not match expected value");
322
            assert.equal(response['confirmations'], 2, "'confirmations' does not match expected value");
323
            done();
324
        });
325
    });
326
327
    it('subscribe to new block events', function(done) {
328
        client.subscribeNewBlocks(createdWebhooks[1], function(err, response) {
329
            assert.ifError(err);
330
            assert.ok('event_type' in response, "'event_type' key not in response");
331
            assert.ok('address' in response, "'address' key not in response");
332
            assert.ok('confirmations' in response, "'confirmations' key not in response");
333
            assert.equal(response['event_type'], "block", "'event_type' does not match expected value");
334
            assert.equal(response['address'], null, "'address' does not match expected value");
335
            assert.equal(response['confirmations'], null, "'confirmations' does not match expected value");
336
            done();
337
        });
338
    });
339
340
    it('batch subscribe to address-transaction events', function(done) {
341
        var batchData = [
342
            {
343
                'event_type': 'address-transactions',
344
                'address': '18FA8Tn54Hu8fjn7kkfAygPoGEJLHMbHzo',
345
                'confirmations': 1
346
            },
347
            {
348
                'address': '1LUCKYwD6V9JHVXAFEEjyQSD4Dj5GLXmte',
349
                'confirmations': 1
350
            },
351
            {
352
                'address': '1qMBuZnrmGoAc2MWyTnSgoLuWReDHNYyF'
353
            }
354
        ];
355
        client.batchSubscribeAddressTransactions(createdWebhooks[1], batchData, function(err, response) {
356
            assert.ifError(err);
357
            assert.ok(response);
358
            done();
359
        });
360
    });
361
362
    it('get webhook event subscriptions', function(done) {
363
        client.getWebhookEvents(createdWebhooks[1], function(err, response) {
364
            assert.ifError(err);
365
            assert.ok('data' in response, "'data' key not in response");
366
            assert.ok('total' in response, "'total' key not in response");
367
            assert.equal(parseInt(response['total']), 6, "'total' does not match expected value");
368
            assert.equal(response['data'].length, 6, "Count of event subscriptions returned is not equal to 2");
369
370
            assert.ok('event_type' in response['data'][0], "'event_type' key not in first event subscription of response");
371
372
            done();
373
        });
374
    });
375
376
    it('unsubscribe from address-transaction events', function(done) {
377
        var address = "1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp";
378
        client.unsubscribeAddressTransactions(createdWebhooks[1], address, function(err, response) {
379
            assert.ifError(err);
380
            assert.ok(response);
381
            done();
382
        });
383
    });
384
385
    it('unsubscribe from new transaction events', function(done) {
386
        var transaction = "a0a87b1577d606b349cfded85c842bdc53b99bcd49614229a71804b46b1c27cc";
387
        client.unsubscribeTransaction(createdWebhooks[1], transaction, function(err, response) {
388
            assert.ifError(err);
389
            assert.ok(response);
390
            done();
391
        });
392
    });
393
394
    it('unsubscribe from new block events', function(done) {
395
        client.unsubscribeNewBlocks(createdWebhooks[1], function(err, response) {
396
            assert.ifError(err);
397
            assert.ok(response);
398
            done();
399
        });
400
    });
401
});
402
403
describe('market api', function() {
404
    it('should have a price', function(done) {
405
        client.price(function(err, price) {
406
            assert.ifError(err);
407
            assert.ok(price);
408
            assert.ok(price['USD']);
409
            done();
410
        });
411
    });
412
});
413
414
describe('verify message', function() {
415
    var address = "1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G";
416
    var message = address;
417
    var signature = "H85WKpqtNZDrajOnYDgUY+abh0KCAcOsAIOQwx2PftAbLEPRA7mzXA/CjXRxzz0MC225pR/hx02Vf2Ag2x33kU4=";
418
419
    it('should verify using bitcoinjs-lib', function(done) {
420
        client.verifyMessage(message, address, signature, function(err, result) {
421
            assert.ifError(err);
422
            assert.ok(result);
423
            done();
424
        });
425
    });
426
427
    it('should handle errors nicely', function(done) {
428
        signature = "rubensayshi";
429
        client.verifyMessage(message, address, signature, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
430
            assert.ok(err);
431
            done();
432
        });
433
    });
434
435
    it('should verify using API', function(done) {
436
        client.client.post("/verify_message", null, {message: message, address: address, signature: signature}, function(err, result) {
437
            assert.ifError(err);
438
            assert.ok(result);
439
            done();
440
        });
441
    });
442
});
443
444
describe('send raw', function() {
445
    /**
446
     * @type APIClient
447
     */
448
    var client = blocktrail.BlocktrailSDK({
449
        apiKey : process.env.BLOCKTRAIL_SDK_APIKEY || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APIKEY",
450
        apiSecret : process.env.BLOCKTRAIL_SDK_APISECRET || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APISECRET",
451
        testnet : true
452
    });
453
454
    var tx = "0100000001bee92b36d3092e492e858d1199e46b942b3bddcc4c98071f0d307acced6f7751000000006b48304502210087831790820bf8218dc8df38758660a6f1f54a54d5d45ab0c3384e5ace9253ad0220650bce47447094148d45ec5b9ce4e3008e00723f4de6edd677110b2ebf0ff3da012102d8aa27d34020a6eb06e424787dbbb60f2cf4250a5a1110ab9e15e68fe710abc5ffffffff0131244c00000000001976a914a8d7a8e6724cf3f8ffb92c376ecb0094c18cbaf588ac00000000";
455
456
    // note that -27 (already in blockchain) is only when it's unspent
457
    it("should report TX is already in blockchain", function(done) {
458
        client.sendRawTransaction(tx, function(err, result) {
459
            assert.ok(err);
460
            assert.ok(result.code === -27 || result.code === -25);
461
462
            done();
463
        });
464
    });
465
466
    it('should error decode failed', function(done) {
467
        client.sendRawTransaction(tx.substr(-2), function(err, result) {
468
            assert.ok(err);
469
            assert.equal(-22, result.code);
470
471
            done();
472
        });
473
    });
474
});
475